/**
 * 数组元素可选值为0,1,2
 * 要求将数组排列成{0,0,0,0...,1,1,1,...,2,2,2,...}的形式
 * 
 * 用j遍历我
 * 设置i下标，i之前的都是red
 * 设置k下标，k以后的都是blue
 * 也就是从两头夹着交换，因为只有这样才有边界，如果记录中间的下标，我们并不知道有多少个red
 * 
 * 拓展：其他的情况，如负数，0，正数排序仍然是这样操作
 * 思考：为什么case RED不用考虑a[j]仍为red
 *      而case BLUE要考虑a[j]仍为blue？
 * 
 * 因为red的话，本来就是要留在左边的，即便j++，移动指针导致red留在了左侧，也没有关系
 * blue要移动到后面，假设j和k都是blue导致交换后j还是blue，此时将j右移之后，blue就永远留在了左侧（或者被覆盖）
 */
typedef enum COLOR{RED,WHITE,BLUE} color;//颜色的枚举

void swap(color* a,color* b){
    color temp=*a;
    (*a)=*b;
    (*b)=temp;
}
//要求排序成red ,white blue
void Flag_Array(color a[],int n){
    int i=0,j=0,k=n-1;
    while (j<=k){//这里j<=k即可
        switch (a[j]){
        case RED:
            swap(&a[i],&a[j]);i++;j++;
            break;
        case WHITE: j++;break;
        case BLUE: 
            //这里没有j++，防止交换后a[j]仍然是blue
            //如果有j++则代码是错误的，无法得到正确答案
            swap(&a[k],&a[j]);k--;
        }
    }
}
int main(void){
    enum COLOR arr[]={BLUE,BLUE,BLUE,RED,WHITE,BLUE,RED,WHITE,BLUE,BLUE,BLUE};
    Flag_Array(arr,sizeof(arr)/sizeof(color));
    #include<stdio.h>

    for(int i=0;i<sizeof(arr)/sizeof(color);i++){
        printf("%d ",arr[i]);
        
    }
    return 0;
}